﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Timers;
using System.IO;
using System.Threading;

namespace Principal
{
    public partial class Form1 : Form
    {

        delegate void delegadoNecesarioParaActualizarTamDir(string mensajeTamDir);
        delegate void delegadoNecesarioParaActualizarBarra(int valorMaximo);

        private System.Timers.Timer timer;
        private System.Timers.Timer timerPlugPlay;
        private string[] extensionesValidas;
        private string[] extensionesNoValidas;
        private Mutex mutex;

        //Variable para saber si debo mostrar la alerta (es decir que sea logica)
        private bool alertasLogicas = false;

        Thread hiloCopiaCarpetas;

        Thread hiloCalcularPesoDirectorio;

        delegate void SetTextCallback(int valor);

        public Form1(Dictionary<string,string> parametros, Mutex mutex)
        {

            InitializeComponent();

            this.SetClientSizeCore(this.Size.Width, this.Size.Height);

            // timer de la aplicación
            timer = new System.Timers.Timer();
            timer.Enabled = true;
            timer.Elapsed += new System.Timers.ElapsedEventHandler(CheckKey_Elapsed);
            timer.Interval = 5000;
            // timer de la opción Plug & Play
            timerPlugPlay = new System.Timers.Timer();
            timerPlugPlay.Enabled = true;
            timerPlugPlay.Elapsed += new System.Timers.ElapsedEventHandler(manejadorTimerPlugPlay);
            timerPlugPlay.Interval = 2000;
            // mutex
            this.mutex = mutex;

            this.cargarExtensiones();

            if(checkBox1.Checked)
                tiempoParaSincronizar.Enabled = false;
            if (checkBox4.Checked)
                maximo.Enabled = false;


            this.actualizarParametrosAInterfaz(parametros);

            if (textBoxOrigen.Text == "")
                textBoxOrigen.Text = "C:\\";
            if (textBoxDestino.Text == "")
                textBoxDestino.Text = "C:\\";
        }

        private void cargarExtensiones(object sender, EventArgs e)
        {
            string[] auxiliar = terminacionesValidas.Text.Split(',');
            extensionesValidas = new string[auxiliar.Length];
            int i = 0;

            foreach (string extension in auxiliar)
            {
                extensionesValidas[i] = extension.Trim();
                i++;
            }

            auxiliar = terminacionesNoValidas.Text.Split(',');
            extensionesNoValidas = new string[auxiliar.Length];
            i = 0;

            foreach (string extension in auxiliar)
            {
                extensionesNoValidas[i] = extension.Trim();
                i++;
            }

            //Código agregado
            if (terminacionesNoValidas.Text == "")
                extensionesNoValidas = null;
            if (terminacionesValidas.Text == "")
                extensionesValidas = null;
            //Fin codigo agregado
        }

        private void CheckKey_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            this.button1_Click(sender, new EventArgs());
        }

        /// <summary>
        /// Manejador de timer para sincronizar dispositivos usb
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void manejadorTimerPlugPlay(object sender, System.Timers.ElapsedEventArgs e)
        {
            // si se habilitó la opción de sincronización con dispositivo usb
            if (checkBox5.Checked)
            {
                if (checkBox7.Checked)
                {
                    DriveInfo[] removibles = obtenerRemovibles();

                    try
                    {
                        // si solo detectó un dispositivo removible, lo selecciona para la sincronización
                        if (removibles.Length == 1)
                        {
                            if (radioButtonOrigen.Checked)   // si el usuario seleccionó el dispositivo como origen
                            {
                                textBoxOrigen.Text = removibles[0].Name.ToString();

                                if (textBoxDestino.Text != "")
                                {
                                    // copia el contenido de las carpetas
                                    // copia el contenido de las carpetas
                                    if (hiloCopiaCarpetas == null || !hiloCopiaCarpetas.IsAlive)
                                    {
                                        hiloCopiaCarpetas = new Thread(copiarCarpetas);

                                        hiloCopiaCarpetas.IsBackground = true;
                                        label8.Text = "" + 0;
                                        hiloCopiaCarpetas.Start();
                                    }
                                }
                            }
                            else    // el usuario seleccionó el dispositivo como destino
                            {
                                textBoxDestino.Text = removibles[0].Name.ToString();

                                if (textBoxOrigen.Text != "")
                                {
                                    // copia el contenido de las carpetas
                                    // copia el contenido de las carpetas
                                    if (hiloCopiaCarpetas == null || !hiloCopiaCarpetas.IsAlive)
                                    {
                                        hiloCopiaCarpetas = new Thread(copiarCarpetas);

                                        hiloCopiaCarpetas.IsBackground = true;
                                        label8.Text = "" + 0;
                                        hiloCopiaCarpetas.Start();
                                    }
                                }
                            }
                        }
                        else if (removibles.Length > 1) // hay más de un dispositivo, debe comparar con la etiqueta
                        {
                            int k = 0;
                            bool encontrado = false;
                            string nombre = etiqueta.Text;

                            if (nombre != "")    // si ingresó una etiqueta
                            {
                                while (!encontrado && k < removibles.Length)
                                {
                                    if (removibles[k].VolumeLabel.ToString() == nombre)
                                    {
                                        encontrado = true;
                                    }
                                    else
                                    {
                                        k++;
                                    }
                                }

                                if (encontrado)
                                {
                                    if (radioButtonOrigen.Checked)   // si el usuario seleccionó el dispositivo como origen
                                    {
                                        textBoxOrigen.Text = removibles[k].Name.ToString();

                                        if (textBoxDestino.Text != "")
                                        {
                                            // copia el contenido de las carpetas
                                            copiarCarpetas();
                                        }
                                    }
                                    else    // el usuario seleccionó el dispositivo como destino
                                    {
                                        textBoxDestino.Text = removibles[k].Name.ToString();

                                        if (textBoxOrigen.Text != "")
                                        {
                                            // copia el contenido de las carpetas
                                            copiarCarpetas();
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch
                    {

                    }
                }
            }
        } // fin de manejadorTimerPlugPlay

        private void setTimer(int valor) 
        {
            timer.Interval = valor;
        }

        private void folderBrowserDialog1_HelpRequest(object sender, EventArgs e)
        {

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            textBoxOrigen_TextChanged(this,new EventArgs());
            //CreateMyRichTextBox();
        }

        public void CreateMyRichTextBox()
        {
            richTextBox1.Dock = DockStyle.Fill;


            richTextBox1.LoadFile("C:\\MyDocument.rtf");
            richTextBox1.Find("Text", RichTextBoxFinds.MatchCase);

            richTextBox1.SelectionFont = new Font("Verdana", 12, FontStyle.Bold);
            richTextBox1.SelectionColor = Color.Red;

            //richTextBox1.CanSelect = false;

            richTextBox1.Enabled = false;

            richTextBox1.SaveFile("C:\\MyDocument.rtf", RichTextBoxStreamType.RichText);

            //this.Controls.Add(richTextBox1);
        }

        private string seleccionarCarpeta(string directorioInicial)
        {
            FolderBrowserDialog carpeta = new FolderBrowserDialog();
            carpeta.SelectedPath = directorioInicial;
            carpeta.ShowDialog();
            return carpeta.SelectedPath;
        }

        private void abrirDialogo(object sender, MouseEventArgs e)
        {
            ((TextBox)sender).Text = seleccionarCarpeta(@"C:\Users\fededalla\Documents\Sincronizar Pruebas\Origen");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (hiloCopiaCarpetas==null || !hiloCopiaCarpetas.IsAlive)
            {
                hiloCopiaCarpetas = new Thread(copiarCarpetas);

                hiloCopiaCarpetas.IsBackground = true;

                Controlador.modificarDatosBarra(0, label8, this, progressBar1.Maximum, "");

                hiloCopiaCarpetas.Start();
            }

            //this.copiarCarpetas();
            
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Controlador.modificarBarra(-progressBar1.Value, progressBar1, this);
            Controlador.modificarDatosBarra(0, label8, this, progressBar1.Maximum, "");
            finalizarHilo();
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            try
            {
                if (checkBox1.Checked)
                {
                    this.setTimer(System.Convert.ToInt32(System.Convert.ToDouble(tiempoParaSincronizar.Text) * 60 * 60));
                    timer.Enabled = true;
                }
                else
                    timer.Enabled = false;
            }
            catch 
            {
            
            }
        }

        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            //Hacemos visible el formulario
            this.Show();
            this.WindowState = FormWindowState.Normal;
            //Ocultamos el icono de la bandeja de sistema
            notifyIcon1.Visible = false;
        }

        private void gestionarIcono(object sender, EventArgs e)
        {
                //Si el estado actual de la ventana es "minimizado"...
            if (this.WindowState == FormWindowState.Minimized)
            {
                //Ocultamos el formulario
                this.Visible = false;
                //Hacemos visible el icono de la bandeja del sistema
                notifyIcon1.Visible = true;

            }
        }

        private void actualizarParametrosAInterfaz(Dictionary<string,string> parametros) 
        {
            try
            {
                textBoxOrigen.Text = parametros["origen"];
                textBoxDestino.Text = parametros["destino"];

                checkBox1.Checked = System.Convert.ToBoolean(parametros["sincronizar"]);
                timer.Enabled = checkBox1.Checked;
                checkBox2.Checked = System.Convert.ToBoolean(parametros["ignorarArchivo"]);
                checkBox3.Checked = System.Convert.ToBoolean(parametros["sincronizarAmbosSentidos"]);
                checkBox4.Checked = System.Convert.ToBoolean(parametros["correrAlIniciar"]);
                tiempoParaSincronizar.Text = parametros["intervaloSincronizar"];
                maximo.Text = parametros["tamArchivos"];
                maxTamDir.Text = parametros["tamDirectorios"];
                checkBox8.Checked = System.Convert.ToBoolean(parametros["ignorarDirectorio"]);
                terminacionesNoValidas.Text = parametros["terminacionesIgnoradas"];
                terminacionesValidas.Text = parametros["terminacionesObligatorias"];
                checkBox6.Checked = System.Convert.ToBoolean(parametros["copiarSoloTerminacionesObligatorias"]);
                checkBox5.Checked = System.Convert.ToBoolean(parametros["reconocerDispositivosUSBPlugAndPlay"]);
                etiqueta.Text = parametros["etiqueta"];
                if (etiqueta.Text != "")
                    etiqueta.Enabled = false;
                checkBox7.Checked = System.Convert.ToBoolean(parametros["habilitarSincronizacionAuto"]);
                radioButtonOrigen.Checked = System.Convert.ToBoolean(parametros["radioButtonOrigen"]);
                radioButtonDestino.Checked = System.Convert.ToBoolean(parametros["radioButtonDestino"]);

            }
            catch
            {
                //MessageBox.Show("El programa ha encontrado que el archivo de configuración se encuentra corrupto. Se restaurará a sus valores por defecto.", "Archivo de configuración inválido", MessageBoxButtons.OK, MessageBoxIcon.Information);
                actualizarParametrosAInterfaz(ConfiguracionInicial.crearConfiguracion());
            }

            /*
            for(int i=0;i<parametros.Length;i++)
                switch (i) 
                {
                    case 0: checkBox1.Checked = System.Convert.ToBoolean(parametros[i]); break;
                    case 1: checkBox2.Checked = System.Convert.ToBoolean(parametros[i]); break;
                    case 2: checkBox3.Checked = System.Convert.ToBoolean(parametros[i]); break;
                    case 3: checkBox4.Checked = System.Convert.ToBoolean(parametros[i]); break;
                    case 4: tiempoParaSincronizar.Text = System.Convert.ToString(parametros[i]); break;
                    case 5: maximo.Text = System.Convert.ToString(parametros[i]); break;
                    /*case 0: break;
                    case 0: break;
                    case 0: break;*/
                    
                //}
        }

        /// <summary>
        /// Modifica las etiquetas de origen o destino con la ruta
        /// correspondiente al dispositivo USB conectado y escogido
        /// para sincronizar su contenido.
        /// </summary>
        private void sincronizarDispositivo()
        {
            DriveInfo[] removibles = obtenerRemovibles();

            try
            {
                // si solo detectó un dispositivo removible, lo selecciona para la sincronización
                if (removibles.Length == 1)
                {
                    if (radioButtonOrigen.Checked)   // si el usuario seleccionó el dispositivo como origen
                    {
                        textBoxOrigen.Text = removibles[0].Name.ToString();

                        if (textBoxDestino.Text != "")
                        {
                            // copia el contenido de las carpetas
                            if (hiloCopiaCarpetas == null || !hiloCopiaCarpetas.IsAlive)
                            {
                                hiloCopiaCarpetas = new Thread(copiarCarpetas);

                                hiloCopiaCarpetas.IsBackground = true;
                                label8.Text = "" + 0;
                                hiloCopiaCarpetas.Start();
                            }
                        }
                    }
                    else    // el usuario seleccionó el dispositivo como destino
                    {
                        textBoxDestino.Text = removibles[0].Name.ToString();

                        if (textBoxOrigen.Text != "")
                        {
                            // copia el contenido de las carpetas
                            if (hiloCopiaCarpetas == null || !hiloCopiaCarpetas.IsAlive)
                            {
                                hiloCopiaCarpetas = new Thread(copiarCarpetas);

                                hiloCopiaCarpetas.IsBackground = true;
                                label8.Text = "" + 0;
                                hiloCopiaCarpetas.Start();
                            }
                        }
                    }
                }
                else if (removibles.Length > 1) // hay más de un dispositivo, debe comparar con la etiqueta
                {
                    int k = 0;
                    bool encontrado = false;
                    string nombre = etiqueta.Text;

                    if (nombre != "")    // si ingresó una etiqueta
                    {
                        while (!encontrado && k < removibles.Length)
                        {
                            if (removibles[k].VolumeLabel.ToString() == nombre)
                            {
                                encontrado = true;
                            }
                            else
                            {
                                k++;
                            }
                        }

                        if (encontrado)
                        {
                            if (radioButtonOrigen.Checked)   // si el usuario seleccionó el dispositivo como origen
                            {
                                textBoxOrigen.Text = removibles[k].Name.ToString();

                                if (textBoxDestino.Text != "")
                                {
                                    // copia el contenido de las carpetas
                                    copiarCarpetas();
                                }
                            }
                            else    // el usuario seleccionó el dispositivo como destino
                            {
                                textBoxDestino.Text = removibles[k].Name.ToString();

                                if (textBoxOrigen.Text != "")
                                {
                                    // copia el contenido de las carpetas
                                    copiarCarpetas();
                                }
                            }
                        }
                        else
                        {
                            MessageBox.Show("Por favor, verifique que la etiqueta corresponda a un dispositivo conectado.");

                            etiqueta.Focus();
                        }
                    }
                    else
                    {
                        MessageBox.Show("Por favor, indique la etiqueta del dispositivo.");

                        etiqueta.Focus();
                    }
                }
            }
            catch
            { 
            
            }
        } // fin del método sincronizarDispositivo

        /// <summary>
        /// Devuelve datos sobre cada uno de los dispositivos removibles
        /// que se encuentran conectados al sistema.
        /// </summary>
        /// <returns></returns>
        private DriveInfo[] obtenerRemovibles()
        {
            DriveInfo[] dispositivos = DriveInfo.GetDrives();
            DriveInfo[] removibles = new DriveInfo[20];

            int i = 0, j = 0;

            // detecta los dispositivos extraíbles
            try
            {
                while (i < dispositivos.Length)
                {
                    if (dispositivos[i].DriveType.ToString() == "Removable")
                    {
                        removibles[j] = dispositivos[i];
                        j++;
                    }

                    i++;
                }

                if (j > 0)
                {
                    DriveInfo[] lista = new DriveInfo[j];
                    int k = 0;

                    while (k < j)
                    {
                        lista[k] = removibles[k];

                        k++;
                    }

                    return lista;
                }
            }
            catch
            {
                MessageBox.Show("Ha ocurrido un error mientras se detectaban los dispositivos extraíbles.");
            }

            return null;

        } // fin del método obtenerRemovibles

        /// <summary>
        /// Busca el dispositivo removible cuya etiqueta es igual
        /// al nombre que se pasa como parámetro.
        /// </summary>
        /// <param name="removibles"></param>
        /// <param name="nombre"></param>
        /// <returns>DriveInfo si el dispositivo existe, null en caso contrario</returns>
        private DriveInfo obtenerRemovible(DriveInfo[] removibles, string nombre)
        {
            bool encontrado = false;
            int i = 0;

            try
            {
                while (!encontrado && i < removibles.Length)
                {
                    if (removibles[i].VolumeLabel == nombre)
                    {
                        encontrado = true;
                    }
                    else
                    {
                        i++;
                    }
                }

                if (encontrado)
                {
                    return removibles[i];
                }

            }
            catch 
            {
                
            }
            return null;
        } // fin del método obtenerRemovible

        /// <summary>
        /// Verifica si existe el dispositivo especificado en la etiqueta.
        /// Si existe lo retorna, en caso contrario retorna null.
        /// </summary>
        private DriveInfo obtenerRemovible()
        {
            if (etiqueta.Text == "")    // aún no ingresó una etiqueta
            {
                checkBox7.Checked = false;
                MessageBox.Show("Por favor, ingrese la etiqueta del dispositivo.");
                etiqueta.Focus();
            }
            else    // ingresó una etiqueta
            {
                // verificamos si el dispositivo con la etiqueta existe
                DriveInfo[] removibles = obtenerRemovibles();

                if (removibles.Length > 0)  // si hay dispositivos removibles conectados
                {
                    // busca el dispositivo especificado en la etiqueta
                    DriveInfo dispositivo = obtenerRemovible(removibles, etiqueta.Text);

                    if (dispositivo != null)    // encontró un dispositivo removible
                    {
                        return dispositivo;
                    }
                }
            }

            return null;
        } // fin del método verificarRemovible

        private void notifyIcon1_MouseDoubleClick_1(object sender, MouseEventArgs e)
        {
            //Hacemos visible el formulario
            this.Show();
            this.WindowState = FormWindowState.Normal;
            //Ocultamos el icono de la bandeja de sistema
            notifyIcon1.Visible = false;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            Dictionary<string,string> diccionarioParametros = new Dictionary<string,string>();
            Exception exAux = null;

            diccionarioParametros.Add("sincronizar",Convert.ToString(checkBox1.Checked));
            diccionarioParametros.Add("ignorarArchivo",Convert.ToString(checkBox2.Checked));
            diccionarioParametros.Add("sincronizarAmbosSentidos",Convert.ToString(checkBox3.Checked));
            diccionarioParametros.Add("correrAlIniciar",Convert.ToString(checkBox4.Checked));
            diccionarioParametros.Add("intervaloSincronizar",Convert.ToString(tiempoParaSincronizar.Text));
            diccionarioParametros.Add("tamArchivos",Convert.ToString(maximo.Text));
            diccionarioParametros.Add("ignorarDirectorio", Convert.ToString(checkBox8.Checked));
            diccionarioParametros.Add("tamDirectorios", Convert.ToString(maxTamDir.Text));
            diccionarioParametros.Add("terminacionesIgnoradas", terminacionesNoValidas.Text);
            diccionarioParametros.Add("terminacionesObligatorias", terminacionesValidas.Text);
            diccionarioParametros.Add("copiarSoloTerminacionesObligatorias", Convert.ToString(checkBox6.Checked));
            diccionarioParametros.Add("reconocerDispositivosUSBPlugAndPlay", Convert.ToString(checkBox5.Checked));
            diccionarioParametros.Add("habilitarSincronizacionAuto", Convert.ToString(checkBox7.Checked));
            diccionarioParametros.Add("etiqueta", etiqueta.Text);
            diccionarioParametros.Add("radioButtonOrigen", Convert.ToString(radioButtonOrigen.Checked));
            diccionarioParametros.Add("radioButtonDestino", Convert.ToString(radioButtonDestino.Checked));
            diccionarioParametros.Add("origen", textBoxOrigen.Text);
            diccionarioParametros.Add("destino", textBoxDestino.Text);

            if((exAux = ConfiguracionInicial.guardarConfiguracion(diccionarioParametros))==null)
                MessageBox.Show("Configuracion guardada exitosamente");
            else
                MessageBox.Show(exAux.Message);

           // StreamWriter fs = new StreamWriter(System.IO.Directory.GetCurrentDirectory() + "\\config.data");

           ///* DriveInfo[] dispositivos = DriveInfo.GetDrives();
           // DriveInfo[] removibles = new DriveInfo[20];
           // */

            
           // fs.WriteLine(checkBox1.Checked); //Sincronizar 
           // fs.WriteLine(checkBox2.Checked); //IgnorarArchivos
           // fs.WriteLine(checkBox3.Checked); //SincronizarAmbosSentidos
           // fs.WriteLine(checkBox4.Checked); //CorrerAlIniciar
           // fs.WriteLine(tiempoParaSincronizar.Text); //ItervaloSincronizar
           // fs.WriteLine(maximo.Text); //TamArchivos

           // fs.Close();
            
           // /*FileInfo aux = new FileInfo(System.IO.Directory.GetCurrentDirectory() + "\\config.data");

           // MessageBox.Show(aux.Extension);*/
            
        }

        private void radioButton5_CheckedChanged(object sender, EventArgs e)
        {
            if(radioButtonOrigen.Checked)
                radioButtonDestino.Checked = false;

            checkBox7.Checked = false;
        }

        private void radioButton6_CheckedChanged(object sender, EventArgs e)
        {
            if(radioButtonDestino.Checked)
                radioButtonOrigen.Checked = false;

            checkBox7.Checked = false;
        }

        private void checkBox5_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox5.Checked)  // si se habilitó la sincronización con un dispositivo USB
            {
                // se habilitan las opciones
                groupBoxUSB.Enabled = true;
                etiqueta.Enabled = true;
                radioButtonOrigen.Enabled = true;
                radioButtonDestino.Enabled = true;

                if (etiqueta.Text != "" && checkBox7.Checked)    // si hay un valor como etiqueta y se habilitó la sincronización automática
                {
                    // se habilitó la sincronización automática
                    // obtenemos los directorios de origen y destino
                    string origen = textBoxOrigen.Text;
                    string destino = textBoxDestino.Text;

                    // si el dispositivo removible es el directorio de origen
                    if (radioButtonOrigen.Checked)
                    {
                        if (MessageBox.Show("Los datos del dispositivo USB se copiarán en la carpeta " + destino + ". Está seguro que desea continuar?", "Confirm delete", MessageBoxButtons.YesNo) == DialogResult.Yes)
                        {
                            // actualiza las carpetas origen y destino pare efectuar la copia
                            // luego efectua la copia propiamente dicha
                            sincronizarDispositivo();
                        }
                        else
                        {
                            checkBox5.Checked = false;
                        }
                    }
                    else    // el dispositivo removible es el directorio de destino
                    {
                        if (MessageBox.Show("Los datos de la carpeta " + destino + " se copiarán al dispositivo USB. Está seguro que desea continuar?", "Confirm delete", MessageBoxButtons.YesNo) == DialogResult.Yes)
                        {
                            sincronizarDispositivo();
                        }
                        else
                        {
                            checkBox5.Checked = false;
                        }
                    }
                }
            }
            else    // se deshabilitó la sincronización con un dispositivo USB
            {
                // se deshabilitan las opciones
                groupBoxUSB.Enabled = false;
                etiqueta.Enabled = false;
                radioButtonOrigen.Enabled = false;
                radioButtonDestino.Enabled = false;

                // si estaba sincronizando automaticamente
                if(checkBox7.Checked)
                {
                    // si el hilo estaba ejecutándose
                    if (hiloCopiaCarpetas.IsAlive)
                    {
                        // finaliza su ejecución
                        hiloCopiaCarpetas.Abort();
                    }
                }
            }
        }

        private void etiqueta_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (etiqueta.Text != "")    // si ingresó una etiqueta
            {
                if (e.KeyChar == '\r')  // si presionó ENTER
                {
                    sincronizarDispositivo();
                }
            }
        }

        private void etiqueta_Leave(object sender, EventArgs e)
        {
            if (etiqueta.Text != "")    // si ingresó una etiqueta
            {
                sincronizarDispositivo();
            }
        }

        private void cargarExtensiones()
        {

        }

        private void liberarMutex(object sender, FormClosedEventArgs e)
        {
            mutex.ReleaseMutex();
        }

        private void checkBox4_CheckedChanged(object sender, EventArgs e)
        {

        }

        private void validarCheck4(object sender, EventArgs e)
        {
            try
            {
                if (System.Convert.ToDouble(maximo.Text) < 0)
                    maximo.Text = "" + ((-1) * System.Convert.ToDouble(maximo.Text));
            }
            catch
            {
                checkBox4.Checked = false;
                MessageBox.Show("Tamaño de archivo inválido");
                maximo.Focus();
                maximo.SelectAll();
            }
            finally
            {
                if (checkBox4.Checked)
                    maximo.Enabled = false;
                else
                {
                    maximo.Enabled = true;
                    maximo.Focus();
                    maximo.SelectAll();
                }
            }
        }

        private void validarCheck8(object sender, EventArgs e)
        {
            try
            {
                if (System.Convert.ToDouble(maxTamDir.Text) < 0)
                    maximo.Text = "" + ((-1) * System.Convert.ToDouble(maxTamDir.Text));
            }
            catch
            {
                checkBox8.Checked = false;
                MessageBox.Show("Tamaño de directorio inválido");
                maximo.Focus();
                maximo.SelectAll();
            }
            finally
            {
                if (checkBox8.Checked)
                    maxTamDir.Enabled = false;
                else
                {
                    maxTamDir.Enabled = true;
                    maxTamDir.Focus();
                    maxTamDir.SelectAll();
                }
            }
        }

        private void validarCheck1(object sender, EventArgs e)
        {
            try
            {
                if (System.Convert.ToDouble(tiempoParaSincronizar.Text) < 0)
                    tiempoParaSincronizar.Text = "" + ((-1) * System.Convert.ToDouble(tiempoParaSincronizar.Text));
            }
            catch
            {
                checkBox1.Checked = false;
                MessageBox.Show("Tiempo inválido");
                tiempoParaSincronizar.Focus();
                tiempoParaSincronizar.SelectAll();
            }
            finally
            {
                if (checkBox1.Checked)
                    tiempoParaSincronizar.Enabled = false;
                else
                {
                    tiempoParaSincronizar.Enabled = true;
                    tiempoParaSincronizar.Focus();
                    tiempoParaSincronizar.SelectAll();
                }
            }
        }

        private void validarCheck7(object sender, EventArgs e)
        {
        }

        private void checkBox6_CheckedChanged(object sender, EventArgs e)
        {


        }


        private void checkBox3_CheckedChanged(object sender, EventArgs e)
        {


        }

        private void checkBox7_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox7.Checked)
            {
                // se habilitó la sincronización automática
                // obtenemos los directorios de origen y destino
                string origen = textBoxOrigen.Text;
                string destino = textBoxDestino.Text;

                // si el dispositivo removible es el directorio de origen
                if (radioButtonOrigen.Checked)
                {
                    if (MessageBox.Show("Los datos del dispositivo USB se copiarán en la carpeta " + destino + ". Está seguro que desea continuar?", "Confirm delete", MessageBoxButtons.YesNo) == DialogResult.Yes)
                    {
                        // actualiza las carpetas origen y destino pare efectuar la copia
                        // luego efectua la copia propiamente dicha
                        sincronizarDispositivo();
                    }
                    else
                    {
                        checkBox7.Checked = false;
                    }
                }
                else    // el dispositivo removible es el directorio de destino
                {
                    if (MessageBox.Show("Los datos de la carpeta " + destino + " se copiarán al dispositivo USB. Está seguro que desea continuar?", "Confirm delete", MessageBoxButtons.YesNo) == DialogResult.Yes)
                    {
                        // actualiza las carpetas origen y destino pare efectuar la copia
                        // luego efectua la copia propiamente dicha
                        sincronizarDispositivo();
                    }
                    else
                    {
                        checkBox7.Checked = false;
                    }
                }
            }
            else    // se desactivó la opción de sincronización automática
            {
                // si el hilo estaba ejecutándose
                if (hiloCopiaCarpetas!=null && hiloCopiaCarpetas.IsAlive)
                {
                    // finaliza su ejecución
                    hiloCopiaCarpetas.Abort();
                }
            }
        }

        private void copiarCarpetas() 
        {
            string destino = @textBoxDestino.Text;
            string origen = @textBoxOrigen.Text;
            double max;
            double tamMaxCarpeta = -1;

            Controlador.modificarBarra(-progressBar1.Value, progressBar1, this);

            alertasLogicas = deboMostrarAlertas();
            this.alertarInicioSincronizacion();

            try
            {
                max = System.Convert.ToDouble(maximo.Text);
            }
            catch
            {
                max = 0.0;
            }

            try
            {
                tamMaxCarpeta = System.Convert.ToDouble(maxTamDir.Text);
            }
            catch
            {
                tamMaxCarpeta = 0.0;
            }

            //¿No tengo idea por que este número 1e308?
            if (!checkBox8.Checked)
                tamMaxCarpeta = 1e308;

            if (!checkBox4.Checked)
                max = 1e308;

            Controlador.copiarCarpetas(origen, destino, max, tamMaxCarpeta, extensionesValidas, extensionesNoValidas,checkBox6.Checked,progressBar1,this, this.label8);

            if (checkBox2.Checked)
                Controlador.copiarCarpetas(destino, origen, max, tamMaxCarpeta, extensionesValidas, extensionesNoValidas, checkBox6.Checked, progressBar1, this, this.label8);

            this.alertarFinSincronizacion();

            //TODO ver Antes de finalizar el hilo me aseguro de llenar la barra y de mostrar el estado "Finalizado"
            Controlador.modificarBarra(999999999, progressBar1, this);
            Controlador.modificarDatosBarra(999999999, label8, this, progressBar1.Maximum, "Finalizando...");

            this.finalizarHilo();
        }

        private void alertarInicioSincronizacion()
        {
            if (this.WindowState == FormWindowState.Minimized && alertasLogicas)
            {
                notifyIcon1.BalloonTipIcon = ToolTipIcon.Warning;
                notifyIcon1.BalloonTipTitle = "Sincronizando carpetas automáticamente";
                notifyIcon1.BalloonTipText = "Aguarde mientras el programa sincroniza las carpetas";
                notifyIcon1.ShowBalloonTip(10);
            }
        }

        private void validarCheck6(object sender, EventArgs e)
        {
            if (terminacionesValidas.Text == "")
            {
                checkBox6.Checked = false;
                MessageBox.Show("Escriba al menos una extensión de archivo");
                terminacionesValidas.Focus();
            }
            else
            {
                terminacionesNoValidas.Enabled = !terminacionesNoValidas.Enabled;
                terminacionesValidas.Enabled = !terminacionesValidas.Enabled;
            }
        }

        private void checkBox3_Click(object sender, EventArgs e)
        {


        }

        private void textBoxOrigen_TextChanged(object sender, EventArgs e)
        {
            hiloCalcularPesoDirectorio = new Thread(actualizarPesoDirectorio);

            if (hiloCalcularPesoDirectorio.IsAlive)
                hiloCalcularPesoDirectorio.Abort();

            label6.Text = "Calculando tamaño de directorio...";

            if (hiloCalcularPesoDirectorio == null || !hiloCalcularPesoDirectorio.IsAlive)
            {
                hiloCalcularPesoDirectorio = new Thread(actualizarPesoDirectorio);

                hiloCalcularPesoDirectorio.IsBackground = true;

                hiloCalcularPesoDirectorio.Start();

            }
        }

        private void actualizarPesoDirectorio()
        {
            try
            {
                System.IO.DirectoryInfo directorioOrigen = new System.IO.DirectoryInfo(textBoxOrigen.Text);
                long pesoDir = ObtenerPesoDirectorioEnBytes(directorioOrigen);

                if(pesoDir == 0)
                    modificarMensajeTamDir("Tamaño del directorio: < " + (((pesoDir / 1024) / 1024) + 1) + " MB");
                else
                    modificarMensajeTamDir("Tamaño del directorio: " + ((pesoDir / 1024) / 1024) + " MB");

                

                modificarBarraDesdeSubProceso(Convert.ToInt32(pesoDir / 1024));
            }
            catch
            {
                modificarMensajeTamDir("Directorio origen inválido");
            }
        }

        public void modificarBarraDesdeSubProceso(int valorMaximo)
        {
            if (progressBar1.InvokeRequired)
            {
                delegadoNecesarioParaActualizarBarra del = new delegadoNecesarioParaActualizarBarra(modificarBarraDesdeSubProceso);
                this.Invoke(del, new object[] { valorMaximo });
            }
            else
                progressBar1.Maximum = valorMaximo;
        }

        public void modificarMensajeTamDir(string mensaje)
        {
            if (label6.InvokeRequired)
            {
                delegadoNecesarioParaActualizarTamDir del = new delegadoNecesarioParaActualizarTamDir(modificarMensajeTamDir);
                this.Invoke(del, new object[] { mensaje });
            }
            else
            {
                label6.Visible = true;
                label6.Text = mensaje;
            }
        }

        private long ObtenerPesoDirectorioEnBytes(DirectoryInfo d)
        {

            long pesoDir = 0;

            try
            {

                // Totalizar tamaño de archivos 

                FileInfo[] fis = d.GetFiles();

                foreach (FileInfo fi in fis)
                {

                    pesoDir += fi.Length;

                }

                // Totalizar tamaño sub-directorios 

                DirectoryInfo[] dis = d.GetDirectories();

                foreach (DirectoryInfo di in dis)
                {

                    pesoDir += ObtenerPesoDirectorioEnBytes(di);
                }

            }

            catch
            {

                // Código para la excepción va aquí 

            }

            return pesoDir;

        }

        private void button3_Click(object sender, EventArgs e)
        {
            MessageBox.Show("" + progressBar1.Value);
        }
        

        public void alertarFinSincronizacion() 
        {
            if (this.WindowState == FormWindowState.Minimized && alertasLogicas)
            {
                notifyIcon1.BalloonTipIcon = ToolTipIcon.Warning;
                notifyIcon1.BalloonTipTitle = "Sincronización automática finalizada";
                notifyIcon1.BalloonTipText = "Gracias por utilizar el programa";
                notifyIcon1.ShowBalloonTip(10);
            }
        }

        public void finalizarHilo()
        {
            if(hiloCopiaCarpetas!=null && hiloCopiaCarpetas.IsAlive)
                hiloCopiaCarpetas.Abort();

            
        }

        public bool deboMostrarAlertas() 
        {
            long diferencia = ObtenerPesoDirectorioEnBytes(new System.IO.DirectoryInfo(textBoxOrigen.Text)) - ObtenerPesoDirectorioEnBytes(new System.IO.DirectoryInfo(textBoxDestino.Text));
            if (diferencia > 20 * 1024 * 1024) //si la diferencia es mayor a 10 MB
                return true;
            return false;
        }

        private void habilitarEdicionEtiqueta(object sender, MouseEventArgs e)
        {
            if (checkBox7.Checked)
            {
                checkBox7.Checked = false;
                etiqueta.Enabled = true;
                etiqueta.Focus();
                etiqueta.SelectAll();
            }
        }

        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void groupBoxUSB_Enter(object sender, EventArgs e)
        {

        }
    }
}
